<?php
namespace app\plus_exam\controller;
use app\plus_exam\model\Question as QuestionModel;
use app\plus_exam\model\Category as CategoryModel;
/* *
 * 题库管理
 * */
class Question extends Base{
    const   OPTION_SINGLE   = 1;
    const   OPTION_MULTI    = 2;
    const   OPTION_JUDGE    = 3;

    private $judge_option  = ['A' => '正确','B' => '错误'];
    private $option_key = ['A','B','C','D','E','F','G',];

    public $id              = 0;
    public $option_name     = [];
    public $category_list   = [];
    public $question_list   = [];

    private $QuestionModel; 
    private $CategoryModel; 

    public function _initialize() {
        parent::_initialize();
        $this->QuestionModel = new QuestionModel;
        $this->CategoryModel = new CategoryModel;
        $this->option_name = [self::OPTION_SINGLE => '单选题',self::OPTION_MULTI  => '多选题',self::OPTION_JUDGE  => '判断题'];

        $category_list_raw = $this->CategoryModel->select_nopage_lists();
        foreach($category_list_raw as $key => $val) {
            $this->category_list[intval($val['id'])]['id'] = $val['id'];
            $this->category_list[intval($val['id'])]['name'] = $val['name'];
        }
    }

    /**
     * [index 首页]
     */
    public function index(){
        $this->isAuth('plus_exam.question.index');
        $type = input('type/d');
        $keyword = input('keyword/s');
        $pathMaps[] = ['name'=>'<i class="iconfont icon-home"></i> '.lang('lang_question_ui_title'),'url'=>'javascript:;'];
        $editMenu = [];
        switch ($type) {
            case 1:
                $editMenu[] = ['name'=>'<i class="iconfont icon-cjsqm"></i> '.lang('lang_question_dan_add'),'url'=>url('plus_exam/question/add',['type'=>1])];
                $pathMaps[] = ['name'=>'<i class="iconfont icon-arrowright"></i> '.lang('lang_question_dan_add'),'url'=>'javascript:;'];
                break;
            case 2:
                $editMenu[] = ['name'=>'<i class="iconfont icon-cjsqm"></i> '.lang('lang_question_duo_add'),'url'=>url('plus_exam/question/add',['type'=>2])];
                $pathMaps[] = ['name'=>'<i class="iconfont icon-arrowright"></i> '.lang('lang_question_duo_add'),'url'=>'javascript:;'];
                break;
            case 3:
                $editMenu[] = ['name'=>'<i class="iconfont icon-cjsqm"></i> '.lang('lang_question_pan_add'),'url'=>url('plus_exam/question/add',['type'=>3])];
                $pathMaps[] = ['name'=>'<i class="iconfont icon-arrowright"></i> '.lang('lang_question_pan_add'),'url'=>'javascript:;'];
                break;
        }
        $this->assign('pathMaps',json_encode($pathMaps));
        $this->assign('editMenu',json_encode($editMenu));
        $this->question_list = $this->QuestionModel->select_lists(['type' => $type],$keyword);
        $this->make_question_readable();
        $this->assign('keyword',$keyword);
        $this->assign('type',$type);
        $this->assign('question_list',$this->question_list);
        $this->assign('page',$this->question_list->render());
        return $this->fetch(); 
            
    }

    /**
     * [add 添加]
     */
    public function add(){
        $this->isAuth('plus_exam.question.add');
        if (request()->isAjax()) {
            $data = [
                'type'          => input('post.type/d'),
                'category_id'   => input('post.category_id/d'),
                'content'       => input('post.content/s'),
                'option_list'   => input('post.option_list/a'),
                'answer'        => input('post.answer/a')
            ];
            $validate = $this->validate($data,'Question.add');
            if(true !== $validate){
                return json(['code'=>1,'message'=>$validate]);
            }
            $question_type = $data['type'];
            if($question_type === self::OPTION_JUDGE) {
                $option_list = $this->judge_option;
            } else {
                $option_list = $data['option_list'];
            }
            foreach($option_list as $key => $val) {
                $option_list[$key] = trim($val);
            }
            $option_list = array_filter($option_list);
            //题目选项没有填写
            if(empty($option_list)) {
                return json(['code'=>1,'message'=>lang('lang_message_title_option_error')]);
            }
            //题目选项有重复
            if(count($option_list) != count(array_unique($option_list))) {
               return json(['code'=>1,'message'=>lang('lang_message_title_option_error_two')]);
            }
            //题目选项重复
            for($i = 0; $i < count($option_list); $i++) {
                if(!isset($option_list[$this->option_key[$i]])) {
                    return json(['code'=>1,'message'=>lang('lang_message_title_option_error_three')]);
                }
            }

            $need_update_data = array(
                'category_id'   => intval($data['category_id']),
                'type'          => intval($data['type']),
                'content'       => trim($data['content']),
                'options'       => json_encode($option_list),
                'answer'        => $data['answer']
            );

            //题目答案不存在
            if(empty($need_update_data['answer'])) {
               return json(['code'=>1,'message'=>lang('lang_message_answer_error')]);
            }

            //题目答案不存在(单选或判断)
            if(($question_type === self::OPTION_SINGLE) or ($question_type === self::OPTION_JUDGE)) {
                $answers = $need_update_data['answer'][0];
                if(!isset($option_list[$answers])) {
                   return json(['code'=>1,'message'=>lang('lang_message_answer_error')]);
                }
                $need_update_data['answer'] = $answers;

            }else if ($question_type === self::OPTION_MULTI){ //多选 
                $answers = $need_update_data['answer'];
                foreach($answers as $answer) {
                    if(!isset($option_list[$answer])) {
                        return json(['code'=>1,'message'=>lang('lang_message_answer_error')]);
                    }
                }
                sort($answers, SORT_STRING);
                $answers = implode('', array_values($answers));
                $need_update_data['answer'] = $answers;
            }
            $need_update_data['create_time'] = time();
            $need_update_data['update_time'] = time();

            //更新模型数据
            $info = $this->QuestionModel->add_data($need_update_data); 
            if(!$info){
                return json(['code'=>1,'message'=>lang('lang_message_error')]);
            }else{
                return json(['code'=>0,'message'=>lang('lang_message_success'),'data'=>['url'=>url('plus_exam/question/index',['type'=>$data['type']])]]);
            }
        } else {
            $type = input('type/d');
            //菜单
            $pathMaps = [
                ['name'=>'<i class="iconfont icon-arrowleft"></i> '.lang('lang_ui_back'),'url'=>url('plus_exam/question/index',['type'=>$type])]
            ];
            $this->assign('pathMaps',json_encode($pathMaps));
            $editMenu = [];
            $this->assign('editMenu',json_encode($editMenu));
            //菜单
            $type_name = $this->option_name[$type];
            if($type === self::OPTION_SINGLE || $type === self::OPTION_MULTI) {
                $add_option_list = ['A' => '','B' => '','C' => '','D' => ''];
            }else if($type === self::OPTION_JUDGE) {
                $add_option_list = $this->judge_option;
            }
            $category_list = $this->category_list;
            $this->assign('type',$type);
            $this->assign('category_list',$category_list);
            $this->assign('type_name',$type_name);
            $this->assign('add_option_list',$add_option_list);
            return $this->fetch();
        }
    }

    /**
     * [edit 编辑]
     */
    public function edit(){
        $this->isAuth('plus_exam.question.edit');
        if (request()->isAjax()) {
            $data = [
                'id' => input('post.id/d'),
                'type' => input('post.type/d'),
                'category_id' =>input('post.category_id/d'),
                'content' => input('post.content/s'),
                'option_list' => input('post.option_list/a'),
                'answer' => input('post.answer/a')
            ];
            $validate = $this->validate($data,'Question.edit');
            if(true !== $validate){
                return json(['code'=>1,'message'=>$validate]);
            }
            $question_type = $data['type'];
            if($question_type === self::OPTION_JUDGE) {
                $option_list = $this->judge_option;
            } else {
                $option_list = $data['option_list'];
            }
            foreach($option_list as $key => $val) {
                $option_list[$key] = trim($val);
            }
            $option_list = array_filter($option_list);
            if(empty($option_list)) {
                return json(['code'=>1,'message'=>lang('lang_message_title_option_error')]);
            }
            if(count($option_list) != count(array_unique($option_list))) {
               return json(['code'=>1,'message'=>lang('lang_message_title_option_error_two')]);
            }
            for($i = 0; $i < count($option_list); $i++) {
                if(!isset($option_list[$this->option_key[$i]])) {
                    return json(['code'=>1,'message'=>lang('lang_message_title_option_error_three')]);
                }
            }
            $need_update_data = array(
                'id'            => $data['id'],
                'content'       => trim($data['content']),
                'options'       => json_encode($option_list),
                'answer'        => $data['answer']
            );
            if(empty($need_update_data['answer'])) {
               return json(['code'=>1,'message'=>lang('lang_message_answer_error')]);
            }

            if(($question_type === self::OPTION_SINGLE) or ($question_type === self::OPTION_JUDGE)) {
                $answers = $need_update_data['answer'][0];
                if(!isset($option_list[$answers])) {
                   return json(['code'=>1,'message'=>lang('lang_message_answer_error')]);
                }
                $need_update_data['answer'] = $answers;
            } else if ($question_type === self::OPTION_MULTI){
                $answers = $need_update_data['answer'];
                foreach($answers as $answer) {
                    if(!isset($option_list[$answer])) {
                        return json(['code'=>1,'message'=>lang('lang_message_answer_error')]);
                    }
                }
                sort($answers, SORT_STRING);
                $answers = implode('', array_values($answers));
                $need_update_data['answer'] = $answers;
            }
            $need_update_data['update_time'] = time();
            $info = $this->QuestionModel->edit_data($need_update_data); //更新模型数据
            if(!$info){
                return json(['code'=>1,'message'=>lang('lang_error')]);
            }else{
                return json(['code'=>0,'message'=>lang('lang_success'),'data'=>['url'=>url('plus_exam/question/index',['type'=>$data['type']])]]);
            }
        } else {
            $id   = input('id/d');
            $info = $this->QuestionModel->find_info($id);
            //菜单
            $pathMaps = [
                ['name'=>'<i class="iconfont icon-arrowleft"></i> '.lang('lang_ui_back'),'url'=>url('plus_exam/question/index',['type'=>$info['type']])]
            ];
            $this->assign('pathMaps',json_encode($pathMaps));
            $editMenu = [];
            $this->assign('editMenu',json_encode($editMenu));
            //菜单
            $rel_category = $this->CategoryModel->find_info($info['category_id']);
            $this->assign('category',$rel_category['name']);
            $this->assign('category_list',$this->category_list);
            $this->assign('option_list',json_decode($info['options'],true));
            $this->assign('type_name',$this->option_name[$info['type']]);
            $this->assign('info',$info);
            return $this->fetch();
        }
    }

    /**
     * 删除
     * @return [json] 
     */
    public function delete(){
        $this->isAuth('plus_exam.question.delete');
        $id   = input('id/d');
        $result  = $this->QuestionModel->delete_data($id);
        if(!$result){
            return json(['code'=>1,'message'=>lang('lang_error')]);
        }else{
            return json(['code'=>0,'message'=>lang('lang_success')]);
        }
    }

    /**
     * [make_question_readable 遍历题库列表]
     * @return [array] [新的题库列表]
     */
    private function make_question_readable() {
        foreach($this->question_list as $key => $val) {
            $this->question_list[$key] = $this->make_single_question_readable($val);
        }
    }

    /**
     * [make_single_question_readable 转换题库类型和名称]
     * @param  [array] $question [题库列表]
     * @return [array]           [新的题库列表]
     */
    private function make_single_question_readable($question) {
        $question['type_name'] = $this->option_name[intval($question['type'])];
        $question['category']  = $this->category_list[intval($question['category_id'])]['name'];
        $question['option_list'] = json_decode($question['options'],true);
        return $question;
    }
}